﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TA.DotNetUtils
{
	public static class Tuple
	{
		public static Tuple<A, B> Create<A, B>(A item0, B item1)
		{
			return new Tuple<A, B>(item0, item1);
		}
		public static Tuple<A, B, C> Create<A, B, C>(A item0, B item1, C item2)
		{
			return new Tuple<A, B, C>(item0, item1, item2);
		}
		public static Tuple<A, B, C, D> Create<A, B, C, D>(A item0, B item1, C item2, D item3)
		{
			return new Tuple<A, B, C, D>(item0, item1, item2, item3);
		}
	}
	[Serializable]
	public class Tuple<A, B>
	{
		public Tuple(A item0, B item1)
		{
			_item0 = item0;
			_item1 = item1;
		}
		public A Item0
		{
			get
			{
				return _item0;
			}
		}
		public B Item1
		{
			get
			{
				return _item1;
			}
		}
		public override string ToString()
		{
			return this.Item0.ToString() + ", " + this.Item1.ToString();
		}
		public override bool Equals(object obj)
		{
			if (obj is Tuple<A, B>)
				return object.Equals(this._item0, ((Tuple<A, B>)obj)._item0) && object.Equals(this._item1, ((Tuple<A, B>)obj)._item1);
			return false;
		}
		public bool Equals(Tuple<A, B> that)
		{
			if (that == null) return false;
			return object.Equals(this._item0, that._item0) && object.Equals(this._item1, that._item1);
		}
		public override int GetHashCode()
		{
			return new FNVHash32().Hash<int>(this._item0.GetHashCode(), this._item1.GetHashCode());
		}
		A _item0;
		B _item1;
	}
	[Serializable]
	public class Tuple<A, B, C> : Tuple<A, B>
	{
		public Tuple(A item0, B item1, C item2)
			: base(item0, item1)
		{
			_item2 = item2;
		}
		public C Item2
		{
			get
			{
				return _item2;
			}
		}
		public override string ToString()
		{
			return base.ToString() + ", " + this.Item2.ToString();
		}
		public override bool Equals(object obj)
		{
			if (obj is Tuple<A, B, C>)
				return base.Equals((Tuple<A, B, C>)obj) && object.Equals(this._item2, ((Tuple<A, B, C>)obj)._item2);
			return false;
		}
		public bool Equals(Tuple<A, B, C> that)
		{
			if (that == null) return false;
			return base.Equals(that) && object.Equals(this._item2, that._item2);
		}
		public override int GetHashCode()
		{
			return new FNVHash32().Hash<int>(base.GetHashCode(), this._item2.GetHashCode());
		}

		C _item2;
	}
	[Serializable]
	public class Tuple<A, B, C, D> : Tuple<A, B, C>
	{
		public Tuple(A item0, B item1, C item2, D item3)
			: base(item0, item1, item2)
		{
			_item3 = item3;
		}
		public D Item3
		{
			get
			{
				return _item3;
			}
		}
		public override string ToString()
		{
			return base.ToString() + ", " + this.Item3.ToString();
		}
		public override bool Equals(object obj)
		{
			if (obj is Tuple<A, B, C, D>)
				return base.Equals((Tuple<A, B, C, D>)obj) && object.Equals(this._item3, ((Tuple<A, B, C, D>)obj)._item3);
			return false;
		}
		public bool Equals(Tuple<A, B, C, D> that)
		{
			if (that == null) return false;
			return base.Equals(that) && object.Equals(this._item3, that._item3);
		}
		public override int GetHashCode()
		{
			return new FNVHash32().Hash<int>(base.GetHashCode(), this._item3.GetHashCode());
		}

		D _item3;
	}

}
